package com.be.beadmin.basicData.impl;

import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSONArray;

import com.be.beadmin.basicData.dto.input.RoleDto;
import com.be.beadmin.basicData.dto.input.RoleMenusDto;
import com.be.beadmin.basicData.dto.output.LabelValue;
import com.be.beadmin.basicData.dto.output.RoleEx;
import com.be.beadmin.basicData.entity.Menu;
import com.be.beadmin.basicData.entity.Role;
import com.be.beadmin.basicData.entity.Role_;
import com.be.beadmin.basicData.mapper.RoleDtoMapper;
import com.be.beadmin.basicData.mapper.RoleMapper;
import com.be.beadmin.basicData.repository.MenuRepository;
import com.be.beadmin.basicData.repository.RoleRepository;
import com.be.beadmin.basicData.service.RoleService;
import com.be.beadmin.common.entity.PageEntity;

import com.be.beadmin.common.exception.BeadminException;
import com.be.beadmin.common.utils.JpaQueryBuilder;
import com.be.beadmin.common.utils.JpaQueryBuilderNew;
import com.be.beadmin.common.utils.JpaSortBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;

import javax.persistence.criteria.Order;
import javax.persistence.criteria.Predicate;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

@Service
public class RoleServiceImpl implements RoleService {

    @Autowired
    RoleRepository roleRepository;

    @Autowired
    RoleMapper roleMapper;

    @Autowired
    RoleDtoMapper roleDtoMapper;

    @Autowired
    MenuRepository menuRepository;



    @Override
    public Page<RoleEx> getRoleByPage(PageEntity pageEntity) {

        Pageable pageable = PageRequest.of(
                pageEntity.getCurrent() -1,
                pageEntity.getPageSize());
        Page<Role> page = roleRepository.findAll((root, criteriaQuery, criteriaBuilder) -> {
                    List<Predicate> list = new ArrayList<>();
                    Predicate pre1 =   JpaQueryBuilderNew.getPredicate(root, pageEntity.getFilters(), criteriaBuilder);
                    list.add(pre1);
                    Predicate pre2 = criteriaBuilder.equal(root.get(Role_.delete), 0); //过滤为0
                    list.add(pre2);
                    Predicate[] p = new Predicate[list.size()];
                    List<Order> orders = new ArrayList<>();
                    if(pageEntity.getSorters() != null && pageEntity.getSorters().size() > 0) {
                        orders = JpaSortBuilder.getPredicate(root, pageEntity.getSorters(), criteriaBuilder);
                        criteriaQuery.orderBy(orders);
                    } else {
                        criteriaQuery.orderBy(criteriaBuilder.desc(root.get(Role_.createTime).as(Date.class)));
                    }

                    return  criteriaBuilder.and(list.toArray(p));
                }
                , pageable);
        Page<RoleEx> page1 = page.map(roleMapper::toEntity);
        return page1;
    }

    @Override
    public void addRole(RoleDto roleDto) {
        Role result = roleRepository.findRoleByCodeAndDelete(roleDto.getCode(), 0);
        if(ObjectUtil.isNotEmpty(result)) {
            throw new BeadminException("该角色已经存在请重新添加");
        }
        Role role = new Role();
        role.setName(roleDto.getName());
        role.setCode(roleDto.getCode());
        role.setDescription(roleDto.getDescription());
        roleRepository.save(role);
    }

    @Override
    public void updateRole(RoleDto roleDto) {
        Role role = roleRepository.findRoleById(roleDto.getId());
        role = roleDtoMapper.toEntity(roleDto);
        roleRepository.save(role);
    }

    @Override
    public void delRole(RoleDto roleDto) {
        Role role = roleRepository.findRoleById(roleDto.getId());
        if(role.getSystem()) {
            throw new BeadminException("该角色是系统角色不能删除");
        }
        role.setDelete(1);
        roleRepository.save(role);
    }

    @Override
    public void delRoles(List<RoleDto> roleDtos) {

    }

    @Override
    public void saveMenus(RoleMenusDto roleMenusDto) {

        Role role = roleRepository.findRoleById(roleMenusDto.getRoleId());
        Set<Menu> menus = menuRepository.findMenusByDeleteAndIdIn(0 , roleMenusDto.getMenuIds());
        role.setMenus(menus);
        roleRepository.save(role);
    }

    @Override
    public JSONArray getMenuTreeByRole(String roleid) {
        return null;
    }

    @Override
    public List<String> getPermissionById(String roleId) {
        Role role = roleRepository.findRoleById(roleId);
        //角色下已有的菜单
        Set<Menu> menuExist = role.getMenus();
        // 获取下面所有菜单
        List<Menu> menus =  menuRepository.findMenusByDeleteAndParentMenuOrderBySeq(0,null);
        List<String> ids = new ArrayList<>();
        for(Menu menu : menus){
            recursiveModel2(menu,menuExist, ids);
        }
        return ids;
    }

    @Override
    public List<LabelValue> getRoleList() {
        PageEntity pageEntity = new PageEntity();
        pageEntity.setCurrent(1);
        pageEntity.setPageSize(200);
        Page<RoleEx> roleExPage = getRoleByPage(pageEntity);
        List<RoleEx> roleExes = roleExPage.getContent();
        List<LabelValue> labelValues = roleExes.stream().map(item -> {
            LabelValue labelValue = new LabelValue();
            labelValue.setValue(item.getId());
            labelValue.setLabel(item.getName());
            return labelValue;
        }).collect(Collectors.toList());
        return labelValues;
    }


    public List<String> recursiveModel2(Menu menu,Set<Menu> menuExist, List<String> arr){
        if(menu.getChildMenus().size()>0){
            for(Menu child : menu.getChildMenus()){
                recursiveModel2(child,menuExist, arr);
            }
        }else{

            if(menuExist.contains(menu)){
                arr.add(menu.getId());
            }
        }
        return arr;
    }
}
